package com.ruoyi.topic.service.impl;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import com.ruoyi.article.domain.HsArticle;
import com.ruoyi.article.mapper.HsArticleMapper;
import com.ruoyi.related_links.domain.HsRelatedLinks;
import com.ruoyi.related_links.mapper.HsRelatedLinksMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.topic.mapper.HsTopicMapper;
import com.ruoyi.topic.domain.HsTopic;
import com.ruoyi.topic.service.IHsTopicService;

/**
 * 热搜主题Service业务层处理
 * 
 * @author lzk
 * @date 2025-06-17
 */
@Service
public class HsTopicServiceImpl implements IHsTopicService 
{
    @Autowired
    private HsTopicMapper hsTopicMapper;

    @Autowired
    private HsRelatedLinksMapper hsRelatedLinksMapper;

    @Autowired
    private HsArticleMapper hsArticleMapper;

    @Value("${data-clean.topic-path}")
    private String topicPath;

    @Value("${data-clean.related-links-path}")
    private String relatedLinksPath;

    @Value("${data-clean.article-path}")
    private String articlePath;

    @Value("${data-clean.period-days}")
    private int periodDays;

    /**
     * 查询热搜主题
     * 
     * @param id 热搜主题主键
     * @return 热搜主题
     */
    @Override
    public HsTopic selectHsTopicById(Long id)
    {
        return hsTopicMapper.selectHsTopicById(id);
    }

    /**
     * 查询热搜主题列表
     * 
     * @param hsTopic 热搜主题
     * @return 热搜主题
     */
    @Override
    public List<HsTopic> selectHsTopicList(HsTopic hsTopic)
    {
        return hsTopicMapper.selectHsTopicList(hsTopic);
    }

    /**
     * 新增热搜主题
     * 
     * @param hsTopic 热搜主题
     * @return 结果
     */
    @Override
    public int insertHsTopic(HsTopic hsTopic)
    {
        return hsTopicMapper.insertHsTopic(hsTopic);
    }

    /**
     * 修改热搜主题
     * 
     * @param hsTopic 热搜主题
     * @return 结果
     */
    @Override
    public int updateHsTopic(HsTopic hsTopic)
    {
        return hsTopicMapper.updateHsTopic(hsTopic);
    }

    /**
     * 批量删除热搜主题
     * 
     * @param ids 需要删除的热搜主题主键
     * @return 结果
     */
    @Override
    public int deleteHsTopicByIds(Long[] ids)
    {
        return hsTopicMapper.deleteHsTopicByIds(ids);
    }

    /**
     * 删除热搜主题信息
     * 
     * @param id 热搜主题主键
     * @return 结果
     */
    @Override
    public int deleteHsTopicById(Long id)
    {
        return hsTopicMapper.deleteHsTopicById(id);
    }

    /**
     * 清理并导出相关链接和文章
     *
     * @param customPeriod 清理周期（天）
     * @throws Exception 异常
     */
    @Override
    public void cleanAndExport(Integer customPeriod) throws Exception {
        int days = customPeriod != null ? customPeriod : periodDays;
        LocalDateTime threshold = LocalDateTime.now().minusDays(days);

        // 查询
        List<HsTopic> oldTopics = hsTopicMapper.selectOlderThan(threshold);
        List<HsRelatedLinks> oldLinks = hsRelatedLinksMapper.selectOlderThan(threshold);
        List<HsArticle> oldArticles = hsArticleMapper.selectOlderThan(threshold);

        // 导出
        exportToCsv(oldTopics, topicPath, "hs_topic");
        exportToCsv(oldLinks, relatedLinksPath, "hs_related_links");
        exportToCsv(oldArticles, articlePath, "hs_article");

        // 删除
        hsTopicMapper.deleteOlderThan(threshold);
        hsRelatedLinksMapper.deleteOlderThan(threshold);
        hsArticleMapper.deleteOlderThan(threshold);
    }

    /**
     * 导出数据到CSV文件
     *
     * @param data 数据列表
     * @param dirPath 文件保存目录
     * @param tableName 表名
     * @throws IOException 异常
     */
    @Override
    public <T> void exportToCsv(List<T> data, String dirPath, String tableName) throws IOException {
        if (data == null || data.isEmpty()) return;
        File dir = new File(dirPath);
        if (!dir.exists()) dir.mkdirs();
        String fileName = tableName + "_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".csv";
        File file = new File(dir, fileName);
        try (PrintWriter writer = new PrintWriter(file, StandardCharsets.UTF_8)) {
            Field[] fields = data.get(0).getClass().getDeclaredFields();
            writer.println(Arrays.stream(fields).map(Field::getName).collect(Collectors.joining(",")));
            for (T obj : data) {
                writer.println(Arrays.stream(fields).map(f -> {
                    f.setAccessible(true);
                    try { return String.valueOf(f.get(obj)); } catch (Exception e) { return ""; }
                }).collect(Collectors.joining(",")));
            }
        }
    }
}
